/**
 @author 迷途小羔羊
 2014-11-19
 */
namespace GYLite
{
	/**
	 * 加载资源，用于记载资源时，记录资源的一些基本信息
	 * 当要销毁时，请调用其Clear方法，并且把引用设置为null
	 * */
	export class LoadInfo
	{
		public static SEND_RES:number = 1;
		public static SEND_DATA:number = 2;
		public static SEND_HTTP:number = 3;
		public save:boolean=true;
		public path:string;
		public bytes:any;
		public startTime:number;
		private _content;
		public contentType:string;
		public header:Array<any>;
		public type:any;
		public method:string;
		public thisObject:any;
		public param:InfoParam;
		public data:any;
		public progressInfo:any[];
		public retainBytes:boolean;
		public lifeTime:number;
		/**http状态码*/public status:number;
		/**传送类型，参考LoadInfo常量*/public sendType:number;
		private _msg:string;
		private _progFunc:Function;
		private _callBackFunc:Function;
		private _loadVec:Array<LoadInfo>;
		public mimeType:string;
		public version:string;		
		private static _pool;
		// private static _s:Single;
		public constructor()//s:Single
		{
			// if(!s)
			// 	throw(new Error("use getInstance to Create"));
			let s =this;
			s.lifeTime = NaN;
			s.progressInfo = [];
		}
		public get dataFormat():string
		{var s = this;
			if(s.type == LoadType.TYPE_IMAGE || s.type == LoadType.TYPE_TEX)
				return "image";
			else if(s.type == LoadType.TYPE_BINARY || s.type == LoadType.TYPE_SOUND || s.type == LoadType.TYPE_FONT)
				return "arraybuffer";
			else if(s.type == LoadType.TYPE_TEXT || s.type == LoadType.TYPE_JS)
				return "text";
			else if(s.type == LoadType.TYPE_JSON)
				return "json";			
			return "";
		}
		public set callBackFunc(val:Function)
		{
			this._callBackFunc=val;
		}
		/**加载完成回调函数*/
		public get callBackFunc():Function
		{
			return this._callBackFunc;
		}
		public set msg(val:string)
		{
			var s = this;
			s._msg=val;
			var len:number;
			if(s._loadVec==null)
				return;
			len=s._loadVec.length;
			while(--len>-1)
				s._loadVec[len].msg = val;
		}
		/**错误信息*/
		public get error():number
		{
			var s = this;
			var arr:string[] = s._msg.split("#");
			if(arr.length <= 1)
				return 0;
			return Number(arr[arr.length - 1]);
		}
		/**加载信息*/
		public get msg():string
		{
			return this._msg;	
		}
		public set content(val:ResObject)
		{
			var s = this;
			if(!s.save && s._content)
				s._content.clear(false);
			s._content=val;
			if(s._loadVec==null)
				return;
			var len:number;
			len=s._loadVec.length;
			while(--len>-1)
				s._loadVec[len]._content = val;
		}
		public get content():ResObject
		{
			return this._content;	
		}
		/**url路径的名称*/
		public get name():string
		{
			let arr:string[];
			let n:string;
			let s = this;
			n = s.path.split("?")[0];
			arr = n.split("/");
			n = arr[arr.length - 1];
			return n.split(".")[0];
		}
		/**url路径的扩展名*/
		public get ext():string
		{
			let arr:string[];
			let n:string;
			let s = this;
			n = s.path.split("?")[0];
			arr = n.split("/");
			n = arr[arr.length - 1];
			arr = n.split(".");
			return arr[arr.length - 1];
		}
		/**包含资源路径*/
		public includeAssets(path:string):boolean
		{
			let s= this;
			if(s.path == path)
				return true;
			if(s.param && s.param.assets && s.param.assets.length > 0)
			{
				let i:number,len:number;
				len = s.param.assets.length;
				for(i=0;i<len;i+=2)
				{					
					if(s.param.assets[i] == path)
						return true;
				}
			}
			return false;
		}
		public hasRes():boolean
		{
			return this._content && this._content.res;
		}
		/**加载完成，会调用所有关联的回调*/
		public callBack():void
		{
			var s = this;
			if(s._callBackFunc!=null)
				s._callBackFunc.call(s.thisObject,s);
			if(s._loadVec==null)
				return;
			var len:number;
			let loadInfo:LoadInfo;			
			len=s._loadVec.length;
			while(--len>-1)
			{
				loadInfo = s._loadVec[len];
				loadInfo._msg = s._msg;
				if(loadInfo.callBackFunc!=null)
					loadInfo.callBackFunc.call(loadInfo.thisObject,loadInfo);
			}
		}
		/**取消加载请求,当加载请求全部被取消时，自动清理这个LoadInfo
		 * @return 是否已无加载请求
		 * */
		public cancel(callBackFunc:Function, thisObject:any):boolean
		{
			var s = this;
			var len:number=0;
			if(s._loadVec)len=s._loadVec.length;
			if(s._callBackFunc==callBackFunc && s.thisObject == thisObject)
			{
				if(len == 0)
				{
					s.clear();
					return true;
				}
				else
				{
					s.copy(s._loadVec.shift());
				}
				return false;
			}
			while(--len>-1)
			{
				if(s._loadVec[len].callBackFunc==callBackFunc && s.thisObject == thisObject)
					s._loadVec.splice(len,1);
			}			
			return false;
		}
		public set progFunc(val:Function)
		{
			this._progFunc=val;
		}
		/**加载进度回调函数*/
		public get progFunc():Function
		{
			return this._progFunc;
		}
		public prog(e:ProgressEvent):void
		{
			var s = this;
			if(s._progFunc!=null)
				s._progFunc.call(s.thisObject,e);
			var len:number;
			if(s._loadVec==null)
				return;
			len=s._loadVec.length;
			while(--len>-1)
			{
				if(s._loadVec[len].progFunc!=null)
					s._loadVec[len].progFunc.call(s._loadVec[len].thisObject,e);
			}
		}
		/**清理回收*/
		public clear():void
		{
			var s = this;
			LoadInfo._pool.push(this);
			s.path=null;
			s.startTime=0;
			s.progFunc=null;
			s.callBackFunc=null;
			s.contentType=null;
			s.header = null;
			
			s.type=0;
			s.method=null;
			s.msg=null;
			s.bytes = null;
			s.data = null;
			s.status = 404;
			s.sendType = 0;
			s.lifeTime = NaN;
			s.progressInfo.length = 0;
			s.retainBytes = false;
			if(!s.save)
			{
				if(s.content)s.content.dispose();
				s.save = true;				
			}
			else
			{
				if(s.content)
					s.content.checkUse();
			}		
			s.content=null;
			s.thisObject = null;
			s.param = null;
			s.mimeType = null;
			if(s._loadVec)
			{
				let len:number = s._loadVec.length;
				while(--len>-1)
				{
					s._loadVec[len].clear();	
				}
				s._loadVec.length = 0;
			}
		}
		/**同一个url的加载请求，将被添加到第一个加载请求的LoadInfo下面*/
		public addLoadInfo(val:LoadInfo):void
		{
			var s = this;
			var len:number;
			var loadInfo:LoadInfo;
			var func:Function,obj:any;
			if(s._loadVec==null)
				s._loadVec=[];
			len = s._loadVec.length;
			while(--len>-1)
			{
				loadInfo = s._loadVec[len];
				if(loadInfo.param && loadInfo.param.assets)
				{
					func = loadInfo.param.callBackFunc;
					obj = loadInfo.param.thisObject;					
				}
				else 
				{
					func = loadInfo.callBackFunc;
					obj = loadInfo.thisObject;
				}
				if(func == val.callBackFunc && obj == val.thisObject)
					return;
			}
			if(s.param && s.param.assets)
			{
				func = s.param.callBackFunc;
				obj = s.param.thisObject;					
			}
			else 
			{
				func = s.callBackFunc;
				obj = s.thisObject;
			}
			if(func == val.callBackFunc && obj == val.thisObject)
				return;
			s._loadVec.push(val);
		}
		private copy(l:LoadInfo):void
		{
			var s = this;
			s.save = l.save;
			s.path = l.path;
			s.bytes = l.bytes;
			s.startTime = l.startTime;
			s._content = l.content;
			s.type = l.type;
			s.method = l.method;
			s.data = l.data;
			s.contentType = l.contentType;
			s.param = l.param;
			s.mimeType = l.mimeType;
			s.sendType = l.sendType;
			s.lifeTime = l.lifeTime;
			s._msg = l.msg;
			s._progFunc = l.progFunc;
			s._callBackFunc = l.callBackFunc;			
			s.thisObject = l.thisObject;			
			s.progressInfo = l.progressInfo.concat();
			s.retainBytes = l.retainBytes;
		}
			
		public static create():LoadInfo
		{			
			if(!LoadInfo._pool)
			{
				// _s=new Single;
				LoadInfo._pool=[];
			}
			if(LoadInfo._pool.length==0)
				return new LoadInfo();
			return LoadInfo._pool.pop();
		}
	}
	/**当加载atlas时，用户的param参数存放在InfoParam的param，用户无需理会InfoParam格式*/
	export interface InfoParam
	{
		callBackFunc?:Function;
		thisObject?:any;
		/**加载资源集合时，原始附加参数*/param?:any;
		/**加载资源集合时，图集图片的资源路径[路径，加载类型，路径，加载类型]*/
		assets?:any[];
		/**加载资源集合时，图集图片的资源引用*/refResObjects?:ResObject[];		
		[key:string]:any;
	}	
}